package com.assembly.oauth2.service;

import com.alibaba.fastjson.JSONObject;
import com.assembly.entities.Resources;
import com.assembly.entities.SystemUser;
import com.assembly.feign.IFeignSystemController;
import com.assembly.oauth2.exception.ValidateCodeException;
import com.assembly.util.properties.BlogProperties;
import com.assembly.util.properties.WechatProperties;
import com.assembly.util.tools.WxUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Component("weChatUserDetailsService") // 一定不要少了
public class WeChatUserDetailsService implements UserDetailsService {

    @Autowired
    private IFeignSystemController feignSystemController;

    @Override
    public UserDetails loadUserByUsername(String code ) throws UsernameNotFoundException {
        // 1. 判断用户名是否为空
            if (StringUtils.isEmpty(code)) {
                throw new BadCredentialsException("code不能为空");
            }
            Wechat wechat = this.putWXLoginInfo(code);
            if (null==wechat) {
                throw new ValidateCodeException("服务器请求微信接口获取参数失败！");
            }
           // 2. 通过用户名查询数据库中的用户信息
            SystemUser sysUser = feignSystemController.findUserByOpenid(wechat.getOpenId(),2);
            //存储OpenId
            if (sysUser == null) {
                throw new ValidateCodeException("该微信未绑定用户！");
            }
            // 3. 通过用户id去查询数据库的拥有的权限信息
            List<Resources> menuList =
                    feignSystemController.findMenuListByUserId(sysUser.getId());

            // 4. 封装权限信息（权限标识符code）
            List<GrantedAuthority> authorities = null;
            if (CollectionUtils.isNotEmpty(menuList)) {
                authorities = new ArrayList<>();
                for (Resources menu : menuList) {
                    // 权限标识
                    String codes = menu.getCode();
                    authorities.add(new SimpleGrantedAuthority(codes));
                }
            }
            // 5. 构建UserDetails接口的实现类JwtUser对象
            JwtUser jwtUser = new JwtUser(sysUser.getId(), sysUser.getUsername(), sysUser.getAccount(), sysUser.getPassword(),
                    sysUser.getFullName(), sysUser.getImageUrl(), sysUser.getMobile(), sysUser.getEmail(),
                    sysUser.getIsAccountNonExpired(), sysUser.getIsAccountNonLocked(),
                    sysUser.getIsCredentialsNonExpired(), sysUser.getIsEnabled(),wechat.getSessionKey(),wechat.getOpenId(),
                    authorities);
            return jwtUser;
         }

    /***
     * 注入配置文件类
     */
    @Autowired
    private BlogProperties blogProperties;

    /***
     *
     * @param code
     * @return
     */
     private Wechat putWXLoginInfo( String code){
         WechatProperties wechat = blogProperties.getWechat();
         try {
             JSONObject  jsonObj = WxUtil.getUserWXLoginInfo(code, wechat.getAppId(), wechat.getSecret());
             if (jsonObj == null||jsonObj.get("errcode")!=null) {
                 throw new ValidateCodeException("服务器请求微信接口获取参数失败");
             }
             return  new Wechat(jsonObj.get("session_key").toString(),jsonObj.get("openid").toString());
             } catch (IOException e) {
                 e.printStackTrace();
                throw new ValidateCodeException("微信登录服务器内部IO异常！");
             }
         }
}
